package pers.cz.postgirl.core;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * @program: postgirl-client
 * @description: 间谍类，随时会被安插到目标代码中，此类为该工程的核心类，其他所有的代码都是为了处理spy
 * @author: Cheng Zhi
 * @create: 2023-05-28 21:21
 **/
public class Spy implements Serializable {

    /**
     * serialVersionUID很重要，如果序列化的时候不指定serialVersionUID，则jvm会根据编译版本自动生成一个serialVersionUID，如果指定了则根据指定的版本号来进行
     * 序列化和反序列化，如果本次程序要反序列化一个其他服务传递过来的二进制流，如果serialVersionUID不一致则会序列化失败
     */
    private static final long serialVersionUID = -6683457602544464809L;

    public static enum DataType {
        INPUT,
        OUTPUT;
    }
    private String clzName;

    private String methodName;

    private DataType dataType;

    private List<Object> paramTypeList = new ArrayList<Object>();

    private List<Object> paramValueList = new ArrayList<Object>();

    private Object returnType;

    private String realTypeName;

    private String genericsTypeName;

    private Object returnValue;

    private long startTime;

    private long endTime;

    /**
     * 案例Id，该ID需关联到postgirl前台上的CaseID
     */
    private long caseId;

    /**
     * 主键，用来关联出入参，同一个方法的入参和出参的paramKey一定相同
     */
    private long paramKey;

    public long getParamKey() {
        return paramKey;
    }

    public void setParamKey(long paramKey) {
        this.paramKey = paramKey;
    }

    public String getMethodName() {
        return methodName;
    }

    public void setMethodName(String methodName) {
        this.methodName = methodName;
    }

    public List<Object> getParamValueList() {
        return paramValueList;
    }

    public String getRealTypeName() {
        return realTypeName;
    }

    public Class<?> obtainRealRypeClazz() {

        Class<?> aClass = null;
        try {
            aClass = Class.forName(realTypeName);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return aClass;
    }

    public String getGenericsTypeName() {
        return genericsTypeName;
    }

    public void setGenericsTypeName(String genericsTypeName) {
        this.genericsTypeName = genericsTypeName;
    }

    /**
     * 如果是基本数据类型，不必通过getClass().getName()获取。
     * @param realTypeName
     */
    public void setRealTypeName(String realTypeName) {
        this.realTypeName = realTypeName;
    }

    public void setParamValueList(List<Object> paramValueList) {
        this.paramValueList = paramValueList;
    }

    public Object getReturnValue() {
        return returnValue;
    }

    public void setReturnValue(Object returnValue) {
        this.returnValue = returnValue;
    }

    public void addParam(Object data) {
        paramValueList.add(data);
    }

    public void addParam(String paramType, Object paramValue) {
        paramTypeList.add(paramType);
        paramValueList.add(paramValue);
    }

    public void putReturnValue(String key, Object value) {
        returnType = key;
        returnValue = value;
    }

    public void addParam(String paramType, short paramValue) {
        this.addParam(paramType, paramValue + "");
    }

    public void addParam(String paramType, int paramValue) {
        this.addParam(paramType, paramValue + "");
    }

    public void addParam(String paramType, long paramValue) {
        this.addParam(paramType, paramValue + "");
    }

    public void addParam(String paramType, byte paramValue) {
        this.addParam(paramType, paramValue + "");
    }

    public void addParam(String paramType, char paramValue) {
        this.addParam(paramType, paramValue + "");
    }

    public void addParam(String paramType, float paramValue) {
        this.addParam(paramType, paramValue + "");
    }

    public void addParam(String paramType, double paramValue) {
        this.addParam(paramType, paramValue + "");
    }

    public void addParam(String paramType, boolean paramValue) {
        this.addParam(paramType, paramValue + "");
    }

    public void putReturnValue(String key, int value) {
        this.putReturnValue(key, new Integer(value));
    }

    public void putReturnValue(String key, long value) {
        this.putReturnValue(key, new Long(value));
    }

    public void putReturnValue(String key, short value) {
        this.putReturnValue(key, new Short(value));
    }

    public void putReturnValue(String key, byte value) {
        this.putReturnValue(key, new Byte(value));
    }

    public void putReturnValue(String key, char value) {
        this.putReturnValue(key, new Character(value));
    }

    public void putReturnValue(String key, boolean value) {
        this.putReturnValue(key, new Boolean(value));
    }

    public void putReturnValue(String key, float value) {
        this.putReturnValue(key, new Float(value));
    }

    public void putReturnValue(String key, double value) {
        this.putReturnValue(key, new Double(value));
    }

    public String getClzName() {
        return clzName;
    }

    public void setClzName(String clzName) {
        this.clzName = clzName;
    }

    public DataType getDataType() {
        return dataType;
    }

    public void setDataType(DataType dataType) {
        this.dataType = dataType;
    }

    public List<Object> getParamTypeList() {
        return paramTypeList;
    }

    public void setParamTypeList(List<Object> paramTypeList) {
        this.paramTypeList = paramTypeList;
    }

    public Object getReturnType() {
        return returnType;
    }

    public void setReturnType(Object returnType) {
        this.returnType = returnType;
    }

    public long getStartTime() {
        return startTime;
    }

    public void setStartTime(long startTime) {
        this.startTime = startTime;
    }

    public long getEndTime() {
        return endTime;
    }

    public void setEndTime(long endTime) {
        this.endTime = endTime;
    }

    public long getCaseId() {
        return caseId;
    }

    public void setCaseId(Long caseId) {
        this.caseId = caseId;
    }
}
